package com.lzh.hosp.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lzh.hosp.annotation.OperateLog;
import com.lzh.hosp.common.Const;
import com.lzh.hosp.model.*;
import com.lzh.hosp.model.dto.LoginDto;
import com.lzh.hosp.model.dto.PassDto;
import com.lzh.hosp.service.MsmService;
import com.lzh.hosp.utils.RandomUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/sys/user")
@Tag(name = "用户管理")
public class SysUserController extends BaseController {
   @Autowired
   private MsmService msmService;

   @Autowired
   PasswordEncoder passwordEncoder;

   //短信登录
   @PostMapping("phoneLogin")
   public ResponseResult phoneLogin(@RequestBody LoginDto loginDto){
      return sysUserService.phoneLogin(loginDto);
   }

   //发送短信
   @GetMapping("sendCode/{phone}")
   public ResponseResult send(@PathVariable String phone){
      boolean send = false;
      String code = RandomUtil.getSixBitRandom();
      if (!StringUtils.isEmpty(redisCache.getCacheObject(phone))){
         return ResponseResult.fail("验证码尚未过期，请稍后获取");
      }
      try {
         send = msmService.send(phone,code);
         if (send){
            //生成验证码放到redis，设置有效时间
            redisCache.setCacheObject(phone,code,2, TimeUnit.MINUTES);
         }
      } catch (ExecutionException e) {
         e.printStackTrace();
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
      if (send){
         return ResponseResult.ok();
      }else {
         return ResponseResult.fail("验证码发送失败");
      }
   }

   //用户注册
   @PostMapping("register/{code}")
   public ResponseResult register(@Validated @RequestBody SysUser sysUser,@PathVariable String code){
      //判断有无重复的手机账号
      SysUser user = sysUserService.getByPhone(sysUser.getPhone());
      if (!StringUtils.isEmpty(user)){
         return ResponseResult.fail("手机号重复");
      }
      //从redis取出验证码并进行验证
      String phoneCode = (String)redisCache.getCacheObject(sysUser.getPhone());
      if (StringUtils.isEmpty(phoneCode)){
         return ResponseResult.fail("请重新获取验证码");
      }
      if (StringUtils.isEmpty(code)||!code.equals(phoneCode)){
         return ResponseResult.fail("验证码错误");
      }

      sysUser.setCreated(LocalDateTime.now());
      sysUser.setStatu(Const.STATUS_ON);
      String oldPassword = sysUser.getPassword();
      if (StringUtils.isEmpty(oldPassword)) {
         return ResponseResult.fail("密码不能为空");
      }
      String newPassword = passwordEncoder.encode(oldPassword);
      sysUser.setPassword(newPassword);
      // 默认头像
      sysUser.setAvatar(Const.DEFAULT_AVATAR);
      boolean save = sysUserService.save(sysUser);
      if (save){
         return sysUserService.login(new LoginDto(sysUser.getPhone(),oldPassword,null));
      }else{
         return ResponseResult.fail("注册失败");
      }
   }

   //用户登录
   @PostMapping("/login")
   public ResponseResult login(@RequestBody LoginDto user){
      return sysUserService.login(user);
   }

   //用户注销
   @GetMapping("/logout")
   public ResponseResult logout(HttpServletRequest request, HttpServletResponse response){
      String userId = (String) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
      //拿到用户id删除redis中的数据
      redisCache.deleteObject("login:"+userId);
      new SecurityContextLogoutHandler().logout(request, response, SecurityContextHolder.getContext().getAuthentication());
      return ResponseResult.ok("注销成功");
   }

   @GetMapping("/info/{id}")
   @PreAuthorize("hasAuthority('sys:user:list')")
   public ResponseResult info(@PathVariable Long id) {
      SysUser user = sysUserService.getById(id);
      Assert.notNull(user, "找不到该管理员！");
      List<SysRole> roles = sysRoleService.listRolesByUserId(user.getId());
      user.setSysRoles(roles);
      return ResponseResult.ok(user);
   }

   /**
    * 用户自己修改密码
    *
    */
   @PostMapping("/updatePass")
   @Operation(summary = "修改密码")
   public ResponseResult updatePass(@Validated @RequestBody PassDto passDto, Principal principal) {
      SysUser sysUser = sysUserService.getById(principal.getName());
      boolean matches = passwordEncoder.matches(passDto.getCurrentPass(), sysUser.getPassword());
      if (!matches) {
         return ResponseResult.fail("旧密码不正确！");
      }
      sysUser.setPassword(passwordEncoder.encode(passDto.getPassword()));
      sysUser.setUpdated(LocalDateTime.now());
      sysUserService.updateById(sysUser);
      return ResponseResult.ok();
   }

   /**
    * 超级管理员重置密码
    */
   @PostMapping("/repass/{userId}")
   @Operation(summary = "重置密码")
   @PreAuthorize("hasAuthority('sys:user:repass')")
   public ResponseResult repass(@PathVariable Long userId) {
      SysUser sysUser = sysUserService.getById(userId);
      sysUser.setPassword(passwordEncoder.encode(Const.DEFAULT_PASSWORD));
      sysUser.setUpdated(LocalDateTime.now());
      sysUserService.updateById(sysUser);
      return ResponseResult.ok(null);
   }

   @GetMapping("/list")
   @PreAuthorize("hasAuthority('sys:user:list')")
   public ResponseResult page(String username) {
      Page<SysUser> users = sysUserService.page(getPage(),
            new QueryWrapper<SysUser>()
                  .like(!StringUtils.isEmpty(username), "username", username)
      );
      users.getRecords().forEach(u -> {
         u.setSysRoles(sysRoleService.listRolesByUserId(u.getId()));
      });
      return ResponseResult.ok(users);
   }

   @PostMapping("/save")
   @Operation(summary = "新增用户")
   @PreAuthorize("hasAuthority('sys:user:save')")
   public ResponseResult save(@RequestBody SysUser sysUser) {
      //判断有无重复的手机账号
      SysUser user = sysUserService.getByPhone(sysUser.getPhone());
      if (!StringUtils.isEmpty(user)){
         return ResponseResult.fail("手机号重复");
      }
      sysUser.setCreated(LocalDateTime.now());
      sysUser.setStatu(Const.STATUS_ON);
      // 初始默认密码
      sysUser.setPassword(Const.DEFAULT_PASSWORD);
      if (StringUtils.isEmpty(sysUser.getPassword())) {
         return ResponseResult.fail("密码不能为空");
      }
      String password = passwordEncoder.encode(sysUser.getPassword());
      sysUser.setPassword(password);
      // 默认头像
      sysUser.setAvatar(Const.DEFAULT_AVATAR);
      sysUserService.save(sysUser);
      return ResponseResult.ok(sysUser);
   }

   @PostMapping("/update")
   @Operation(summary = "修改用户")
   @PreAuthorize("hasAuthority('sys:user:update')")
   public ResponseResult update(@RequestBody SysUser sysUser) {
      sysUser.setUpdated(LocalDateTime.now());
      if (!StringUtils.isEmpty(sysUser.getPassword())) {
         String password = passwordEncoder.encode(sysUser.getPassword());
         sysUser.setPassword(password);
      }
      sysUserService.updateById(sysUser);
      return ResponseResult.ok(sysUser);
   }

   @PostMapping("/delete")
   @Operation(summary = "删除用户")
   @PreAuthorize("hasAuthority('sys:user:delete')")
   public ResponseResult delete(@RequestBody Long[] ids){
      sysUserService.removeByIds(Arrays.asList(ids));
      sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("user_id", ids));
      return ResponseResult.ok();
   }

   /**
    * 分配角色
    * @return
    */
   @Transactional
   @PostMapping("/role/{userId}")
   @Operation(summary = "分配角色")
   @PreAuthorize("hasAuthority('sys:user:role')")
   public ResponseResult perm(@PathVariable Long userId, @RequestBody Long[] roleIds) {
      System.out.println(roleIds);
      List<SysUserRole> userRoles = new ArrayList<>();
      Arrays.stream(roleIds).forEach(roleId -> {
         SysUserRole userRole = new SysUserRole();
         userRole.setRoleId(roleId);
         userRole.setUserId(userId);
         userRoles.add(userRole);
      });
      sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id", userId));
      sysUserRoleService.saveBatch(userRoles);
      // 清除权限信息
//      SysUser sysUser = sysUserService.getById(userId);
      sysUserService.clearUserAuthorityInfo(userId);
      return ResponseResult.ok(roleIds);
   }
}